﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using KeXin.Model.Config;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace KeXinApi.Code
{
    public static class SwaggerHelper
    {
        /// <summary>
        /// 鉴权
        /// </summary>
        /// <param name="services"></param>
        /// <param name="config">配置文件</param>
        /// <returns></returns>
        public static IServiceCollection AddCustomJWT(this IServiceCollection services,JwtConfig config)
        {
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.SecurityKey)),//与授权签名校验
                        ValidateIssuer = true,
                        ValidIssuer = config.Issuer ,//issuer代表颁发Token的Web应用程序 【MyBlog.JWT】
                        ValidateAudience = true,
                        ValidAudience = config.Audience,//audience是Token的受理者 【MyBlog.Api】
                        ValidateLifetime = true,
                        //ClockSkew = TimeSpan.FromMinutes(60)//各个服务器同步误差时间
                    };
                    options.SaveToken = true;
                });
            return services;
        }

        public class SwaggerDocTag : IDocumentFilter
        {
            /// <summary>
            /// 添加中文注释
            /// </summary>
            /// <param name="swaggerDoc"></param>
            /// <param name="context"></param>
            public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
            {
                swaggerDoc.Tags = new List<OpenApiTag>()
                {
                    //添加对应的控制器描述
                    new OpenApiTag(){Name = "Authoize",Description = "登陆授权 控制器"},
                    new OpenApiTag(){Name = "Admin",Description = "用户相关"},
                    new OpenApiTag(){Name = "Upload",Description = "上传图片示例"},
                    new OpenApiTag(){Name = "DownLoad",Description = "下载示例"},
                    new OpenApiTag(){Name = "MyTest",Description = "测试"},
                    new OpenApiTag(){Name = "Zip",Description = "测试压缩"},
                  
                };
            }
        }
    }

    /// <summary>
    /// 简易版swagger首页BA验证
    /// </summary>
    /// <remarks>
    /// 参考:https://www.cnblogs.com/BFMC/p/17248307.html
    /// </remarks>

    public static class ExpandAuction
    {
        public static IApplicationBuilder UseSwaggerAuthorized(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<SwaggerBasicAuthMiddleware>();
        }
    }

    /// <summary>
    /// Swagger BA授权中间件
    /// </summary>
    public class SwaggerBasicAuthMiddleware
    {
        private readonly RequestDelegate next;

        public SwaggerBasicAuthMiddleware(RequestDelegate next)
        {
            this.next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            if (context.Request.Path.StartsWithSegments("/swagger"))
            {
                string authHeader = context.Request.Headers["Authorization"];
                if (authHeader != null && authHeader.StartsWith("Basic "))
                {
                    // Get the credentials from request header
                    var header = AuthenticationHeaderValue.Parse(authHeader);
                    var inBytes = Convert.FromBase64String(header.Parameter);
                    var credentials = Encoding.UTF8.GetString(inBytes).Split(':');
                    var username = credentials[0];
                    var password = credentials[1];
                    // swagger首页权限验证 用户名和密码都是swagger,有需要就改写
                    if (username.Equals("swagger") && password.Equals("swagger"))
                    {
                        await next.Invoke(context).ConfigureAwait(false);
                        return;
                    }
                }
                context.Response.Headers["WWW-Authenticate"] = "Basic";
                context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            }
            else
            {
                await next.Invoke(context).ConfigureAwait(false);
            }
        }


    }
}
